/**
 * 
 */
package com.simtek.simplayer.controller;

import android.content.Context;
import android.os.Handler;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

/**
 * @author Hitech
 * 
 */
public class GestureController extends GestureDetector.SimpleOnGestureListener {
	public static final short		SEEK_IDLE			= 0;
	public static final short		SEEK_DISABLE		= 1;
	public static final short		SEEK_HORIZONTAL		= 2;
	public static final short		SEEK_LEFT_VERTICAL	= 3;
	public static final short		SEEK_RIGHT_VERTICAL	= 4;

	private short					seekState			= SEEK_IDLE;
	private GestureDetectorCompat	gesture;
	private OnGestureListener		gestureListener;
	private View					touchView;
	private boolean					horizontalSeekable;
	private boolean					verticalSeekable;

	public GestureController(Context context, Handler handler,
			OnGestureListener listener) {
		gesture = new GestureDetectorCompat(context, this, handler);
		this.gestureListener = listener;
	}

	public boolean onTouch(View v, MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			this.touchView = v;
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			this.touchView = null;
			if (this.gestureListener != null) {
				if (seekState != SEEK_IDLE) {
					this.gestureListener.onStopSeek(seekState);
				}
			}
			seekState = SEEK_IDLE;
			break;
		}
		return gesture.onTouchEvent(event);
	}

	public void setHorizontalSeekable(boolean seekable) {
		this.horizontalSeekable = seekable;
	}

	public void setVerticalSeekable(boolean verticalSeekable) {
		this.verticalSeekable = verticalSeekable;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		if (this.gestureListener != null) {
			if (seekState == SEEK_IDLE) {
				if (Math.abs(distanceX) > Math.abs(distanceY)) {
					if (!horizontalSeekable) {
						seekState = SEEK_DISABLE;
						return false;
					} else {
						seekState = SEEK_HORIZONTAL;
					}
				} else {
					int width = this.touchView.getMeasuredWidth();
					if (!verticalSeekable) {
						seekState = SEEK_DISABLE;
						return false;
					} else if (e1.getX() < width / 2) {
						seekState = SEEK_LEFT_VERTICAL;
					} else {
						seekState = SEEK_RIGHT_VERTICAL;
					}

				}

				if (!this.gestureListener.onStartSeek(seekState)) {
					return false;
				}
			}

			switch (seekState) {
			case SEEK_HORIZONTAL:
				return this.gestureListener.onSeek(seekState, -distanceX);
			case SEEK_LEFT_VERTICAL:
			case SEEK_RIGHT_VERTICAL:
				return this.gestureListener.onSeek(seekState, distanceY);
			default:
				return false;
			}
		}
		return super.onScroll(e1, e2, distanceX, distanceY);
	}

	@Override
	public boolean onSingleTapConfirmed(MotionEvent e) {
		if (this.gestureListener != null) {
			return this.gestureListener.onSingleTab();
		}
		return false;
	}

	@Override
	public boolean onDoubleTap(MotionEvent e) {
		if (this.gestureListener != null) {
			return this.gestureListener.onDoubleTab();
		}

		return super.onDoubleTap(e);
	}

	public interface OnGestureListener {
		/**
		 * @param seekMode
		 *            {@link GestureController#SEEK_VERTICAL}
		 *            {@link GestureController#SEEK_HORIZONTAL}
		 */
		public boolean onStartSeek(int seekMode);

		/**
		 * @param seekMode
		 *            {@link GestureController#SEEK_VERTICAL}
		 *            {@link GestureController#SEEK_HORIZONTAL}
		 * @param distanceX
		 */
		public boolean onSeek(int seekMode, float distance);

		/**
		 * @param seekMode
		 *            {@link GestureController#SEEK_VERTICAL}
		 *            {@link GestureController#SEEK_HORIZONTAL}
		 */
		public void onStopSeek(int seekMode);

		public boolean onSingleTab();

		public boolean onDoubleTab();

	}
}
